package com.youxin.chat.pay.service.channel.impl.liantong;

import com.alibaba.fastjson.JSONObject;

import com.youxin.base.BaseResultCode;
import com.youxin.chat.pay.config.PayProperties;
import com.youxin.chat.pay.enums.OrderStatusEnum;
import com.youxin.chat.pay.mapper.ChannelAccountMapper;
import com.youxin.chat.pay.model.ChannelAccount;
import com.youxin.chat.pay.model.ChannelOrder;
import com.youxin.chat.pay.model.UserCash;
import com.youxin.chat.pay.model.UserRecharge;
import com.youxin.chat.pay.service.SequenceService;
import com.youxin.chat.pay.service.channel.IPayChannel;
import com.youxin.chat.pay.enums.PayChannelEnum;
import com.youxin.chat.pay.service.channel.entity.*;

import com.youxin.chat.pay.utils.HttpClientUtil;
import com.youxin.chat.pay.service.channel.impl.liantong.request.LianTongBindCard;
import com.youxin.chat.pay.service.channel.impl.liantong.request.LianTongDefray;
import com.youxin.chat.pay.service.channel.impl.liantong.request.LianTongPay;
import com.youxin.chat.pay.service.channel.impl.liantong.request.LianTongTermination;
import com.youxin.chat.pay.service.channel.impl.liantong.util.LianTongUtil;
import com.youxin.chat.pay.utils.ParamStringUtils;
import com.youxin.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class LiantongPayChannel implements IPayChannel {
    private static final Logger logger = LoggerFactory.getLogger(LiantongPayChannel.class);

    @Resource
    private SequenceService sequenceService;
    @Resource
    private ChannelAccountMapper channelAccountMapper;

    @Resource
    private PayProperties payProperties;


    @Override
    public ChannelResponse bindCard(String orderNo, ChannelBindCard channelBindCard, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject jsonObject = LianTongBindCard.auditBindCardRequest(channelBindCard, channelBindCard.getUserIp(), orderNo, channelAccount.getRsaKeyPri());
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/authpay-sign.authpay.sit.epay/bank-cards";
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard,{}", "联通绑卡回调数据:" + result);
        } catch (Exception e) {
            logger.error("请求绑卡接口失败:", e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求绑卡接口失败");
            return response;
        }
        response.setResult(result);

        return response;


    }

    @Override
    public ChannelResponse validateSms(ChannelBindCardSms channelBindCardSms, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject jsonObject = LianTongBindCard.validateBindSmsRequest(channelBindCardSms, channelAccount.getChannelAccount());
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/authpay-sign.authpay.sit.epay/sign-sms-verification";
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
        } catch (Exception e) {
            logger.error("签约短信验证失败:", e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求接口异常");
            return response;
        }
        if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("回调签名校验失败");
            return response;
        }

        JSONObject object = JSONObject.parseObject(result);

        if ("AUP00000".equalsIgnoreCase(object.getString("rtnCode"))) {
            response.setCode(BaseResultCode.SUCCESS);
            response.setStatus(1);
            response.setResult(result);
        } else {
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setResult(result);
        }

        return response;
    }

    @Override
    public boolean support(String channelCode) {

        if (PayChannelEnum.LIANTONG.getChannelCode().equalsIgnoreCase(channelCode)) {
            return true;
        }
        return false;
    }

    @Override
    public ChannelResponse pay(ChannelPay channelPay, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);

        JSONObject jsonObject = LianTongPay.buildPayRequest(channelPay, channelAccount);
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);

        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/authpay-pay.authpay.sit.epay/pay";
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard,{}", "联通支付回调数据:" + result);

            JSONObject object = JSONObject.parseObject(result);
            if ("AUP00000".equalsIgnoreCase(object.getString("rtnCode"))) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
            } else {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
            }
            if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
                response.setErrorMsg("回调签名校验失败");
            }
        } catch (Exception e) {
            logger.error("请求支付接口失败:", e);
            response.setErrorMsg("请求支付接口失败:");
            return response;
        }


        return response;
    }

    @Override
    public ChannelResponse termination(ChannelTerminationCard channelTerminationCard, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);

        String orderNo = sequenceService.buildChannelOrderNo();
        JSONObject jsonObject = LianTongTermination.auditTerminationRequest(channelTerminationCard, channelAccount, orderNo);
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);

        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/authpay-sign.authpay.sit.epay/sign-cancel";
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard,{}", "联通解约回调数据:" + result);
            JSONObject object = JSONObject.parseObject(result);
            if ("AUP00000".equalsIgnoreCase(object.getString("rtnCode"))) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
            } else {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
            }
            if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
                response.setErrorMsg("回调签名校验失败");
            }

        } catch (Exception e) {
            logger.error("请求解约接口失败:", e);
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "请求解约接口失败");
        }

        return response;
    }

    @Override
    public ChannelNotifyResponse orderNotify(ChannelNotifyRequest request, ChannelAccount channelAccount) {
        JSONObject jsonObject = JSONObject.parseObject(request.getData());
        ChannelNotifyResponse channelNotifyResponse = new ChannelNotifyResponse();

        if ("AUP00000".equalsIgnoreCase(jsonObject.getString("rtnCode")) &&
                LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), request.getData())) {
            JSONObject object = new JSONObject();
            object.put("rtnCode", "AUP00000");
            object.put("rtnMsg", "交易成功");
            channelNotifyResponse.setResponseText(object.toJSONString());
            channelNotifyResponse.setOrderNo(request.getOrderNo());
            channelNotifyResponse.setStatus(OrderStatusEnum.PAY_SUCCESS.getStatus());
        } else {
            JSONObject object = new JSONObject();
            object.put("rtnCode", "FAIL");
            object.put("rtnMsg", "回调签名校验失败");
            channelNotifyResponse.setResponseText(object.toJSONString());
            channelNotifyResponse.setOrderNo(request.getOrderNo());
            channelNotifyResponse.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
        }

        return channelNotifyResponse;
    }

    @Override
    public ChannelNotifyResponse defrayNotify(ChannelNotifyRequest request, ChannelAccount channelAccount) {
        return null;
    }

    @Override
    public ChannelResponse payQuery(ChannelOrder channelOrder, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);

        JSONObject jsonObject = LianTongPay.buildPayExceptionRequest(channelOrder.getChannelOrderNo(), channelAccount);
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);

        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/authpay-pay.authpay.sit.epay/pay-query";
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard,{}", "联通支付结果查询回调数据:" + result);
            JSONObject object = JSONObject.parseObject(result);
            if ("AUP00000".equalsIgnoreCase(object.getString("rtnCode"))) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
            } else {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
            }
            if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
                response.setErrorMsg("回调签名校验失败");
            }
        } catch (Exception e) {
            logger.error("请求支付结果查询接口失败:", e);
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "请求支付结果查询接口失败");
        }

        response.setResult(result);

        return response;
    }

    @Override
    public ChannelResponse defray(ChannelDefray channelDefray, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);

        JSONObject jsonObject = LianTongDefray.buildDefrayRequest(channelDefray, channelAccount, payProperties.getChannel().getNotifyUrl());
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);

        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/" + JSONObject.parseObject(channelAccount.getExtInfo()).getString("defray");
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard，{}", "联通代付回调数据:" + result);
            JSONObject object = JSONObject.parseObject(result);
            if ("Ver1.0.0.2".equalsIgnoreCase(object.getString("repCode"))) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
            } else {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
            }
            if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
                response.setErrorMsg("回调签名校验失败");
            }
        } catch (Exception e) {
            logger.error("请求代付接口失败:", e);
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "请求代付接口失败");
        }

        response.setResult(result);
        return response;
    }

    @Override
    public ChannelResponse defrayQuery(UserCash userCash, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);

        JSONObject jsonObject = LianTongDefray.buildDefrayQueryRequest(userCash, channelAccount);
        String content = ParamStringUtils.toSignStr(jsonObject, "signMsg", "|");
        String signMsg = LianTongUtil.buildSign(content, channelAccount.getRsaKeyPri());
        jsonObject.put("signMsg", signMsg);

        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/" + JSONObject.parseObject(channelAccount.getExtInfo()).getString("defrayQuery");
            result = HttpClientUtil.httpPostRequest(url, jsonObject);
            logger.info("auditBindCard，{}", "联通单笔代付结果查询回调数据:" + result);
            JSONObject object = JSONObject.parseObject(result);
            if ("1".equalsIgnoreCase(object.getString("transRst"))) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
            } else {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
            }
            if (!LianTongUtil.verifySign(channelAccount.getRsaKeyPub(), result)) {
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setResult(result);
                response.setErrorMsg("回调签名校验失败");
            }
        } catch (Exception e) {
            logger.error("请求单笔代付结果查询接口失败:", e);
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "请求单笔代付结果查询接口失败");
        }

        response.setResult(result);
        return response;
    }

    @Override
    public ChannelResponse doChargeSms(ChannelChargeSms channelChargeSms, ChannelAccount channelAccount) {
        return null;
    }

    @Override
    public ChannelResponse balanceQuery(ChannelAccount channelAccount) {
        return null;
    }


}
